package api

import (
	"reflect"
)

import (
	"gitee.com/changeden/jd-union-go-sdk/common"
	"gitee.com/changeden/jd-union-go-sdk/method"
	"gitee.com/changeden/jd-union-go-sdk/pkg"
)

// https://union.jd.com/openplatform/api/v2

type api struct {
	// 组装Api集合
	method.ApiGoodsMethods
	method.ApiEffectMethods
	method.ApiManageMethods
	method.ApiPromotionMethods
	method.ApiSellingMethods
	method.ApiToolMethods

	config *apiConfig

	// 方法插件实例数组
	_apiMethodPlugins []pkg.ApiMethodPlugin
}

func newApi(config *apiConfig) *api {
	inst := &api{
		config: config,
	}
	methodPlugins := getApiMethodPlugin(inst)
	inst._apiMethodPlugins = methodPlugins
	return inst
}

func getApiMethodPlugin(v *api) []pkg.ApiMethodPlugin {
	methodPlugins := make([]pkg.ApiMethodPlugin, 0)
	apiValue := reflect.ValueOf(v).Elem()
	requestFunc := v.request
	var p pkg.ApiMethodPlugin
	var canConv bool
	for i := 0; i < apiValue.NumField(); i++ {
		f := apiValue.Field(i)
		if !(f.IsValid() && f.CanInterface()) {
			continue
		}
		if p, canConv = f.Interface().(pkg.ApiMethodPlugin); !canConv {
			continue
		}
		r := f.FieldByName(common.ApiMethodPluginBaseRequestKey)
		if !(r.IsValid() && r.CanSet()) {
			continue
		}
		r.Set(reflect.ValueOf(requestFunc))
		methodPlugins = append(methodPlugins, p)
	}
	return methodPlugins
}

func (a *api) request(method *pkg.ApiMethod, params pkg.ApiRequestBody, accessToken *string) (*pkg.ApiResponseDTO, error) {
	return NewApiBody(a.config).
		SetMethod(method.Method).
		SetParamJson(params).
		SetAccessToken(accessToken).
		Request(method.ResponseWrapKey)
}
